✨ Vue3开发,或许你需要这样使用请求API 您所在的位置:网站首页 hooks api ✨ Vue3开发,或许你需要这样使用请求API

✨ Vue3开发,或许你需要这样使用请求API

#✨ Vue3开发,或许你需要这样使用请求API| 来源: 网络整理| 查看: 265

大家好,我是vue-hooks-plus的作者,这里和大家分享一下属于Vue3的方便快捷的请求方式是怎么样的。

Vue3 现在已经越来越多小伙伴用上了,在很多技术群中对于Vue3的评价是很高的,在技术博客、群里也会见到很多小伙伴展示自己的 Vue3 代码块以及对 Vue3 项目搭建的一些心得。

相信大部分项目采用了 Vite+Vue3开发,结合网上的资源我发现对于项目整体大架构,比如 状态管理 pinia、开发构建 Vite 、UI 框架 Element-plus 、Vant 、Antd-vue 等主流框架,网络请求 axios 已经有很成熟的搭建使用方案了,咱们搞业务开发,基本上围绕着网络请求打交道,这里和大家聊聊不为人知的、好维护、质量可靠的业务API请求 🫣。

📄 列出我所知的请求使用的方案 二次封装 axios、文件夹统一管理API请求,返回一个 Promise,在组件中使用链式调用 二次封装 axios、文件夹统一管理API请求,返回一个 Promise,在组件中使用 async/await 使用 二次封装axios、全局注入axios,组件内直接调用中这个实例去传参数调用 直接使用 axios 请求(重复繁杂的代码,不利于维护,这里只做举例,不推荐 ❌)

我相信很多小伙伴都属于以上的使用方案,我会逐个和大家分析,谈一下关于 Vue3 网络请求这块的见解。

🔍 分析

二次封装 Axios

const axiosInstance = axios.create({ baseURL: importa.env.VITE_SCREEN_BASE_URL, timeout: 1_000 * 10 }); // ... 省略拦截器 ​ 复制代码

管理API的文件夹

export function getData(params,options){ return new Promise((resolve, reject) => {   axiosInstance({     url,     params,     ...options,   })     .then((res) => {       resolve(res?.data?.data);     })     .catch((err) => {       reject(err);     }); } } 复制代码 链式调用,比较传统 const data = ref() ​ getData({...xxx},{...xxx}).then((res)=>{ // ...这里处理数据 data.value = res.data }).catch(err=>{ // ...xxx }) ​ 复制代码 Async/Await 调用,比较优雅 const data = ref() onMounted(async () => { const res = await getData({...x},{...x}) data.value = res } 复制代码 Provide/Inject 调用,和链式用法基本一致,只是代码量稍少。 main.ts import axios from 'axios' import VueAxios from 'vue-axios' ​ app.use(VueAxios, axios) app.provide('axios', app.config.globalProperties.axios) ​ App.vue const axios: any = inject('axios') // inject axios axios({url,data,...其他配置}).then() // 同上 复制代码 🧑‍💻 看法

我相信很多小伙伴会比较喜欢第二种的 async/await 的语法糖,比较优雅,简洁。

在当今前端业务越来越复杂的环境下,网络请求场景也会变得复杂起来,比如

多次请求拿上一次的数据作为参数体。

某个值变化了又需要重新请求。

或者某个值 满足条件 才开始请求。

对于链式调用来说,是非常不利于代码阅读的,整个业务组件充斥着重复代码,非常不利于维护。

对于 async/await 似乎很好的解决了以上的问题,

第一个 ,await拿上一次 请求参数 的很方便啊! ✅。 第二个,某个值变化了需要重新请求,这里很多小伙伴会想到我把这个请求封装起来,放进watch里面监听执行 ✅ 第三个,在封装的请求函数中加入判断条件是否执行 ✅

上述场景多个组件,多次重复操作,这样文件一多,也存在很多代码重复 ❌

✅ 正确思路

我们需要将这些重复的操作进行封装成 hook,把依赖请求,判断条件是否发起请求这些封装成起来,有执行 async/await 的方法,又有这些依赖请求的功能模块一起联合使用,而用户只需要传递需要开启的功能配置即可;

什么是 hook ?

在 React 中的意思是将一个以 use 开头,含react 状态和 effect 纯函数的外部代码挂入到它的节点当中。

在 Vue 中,我认为将 Vue 的 effect ,如 ref、watch、watchEffect 的外部代码放入vue中执行,也是挂入 hook。

这里我们命名 useRequest

const useRequest = (service,option)=>{   const data = ref()     const run = async ()=>{     const res = await service()     data.value = res   }     // 是否满足条件   if(option.ready){     run()   }     // 依赖重新请求   watch(option.deps,()=>{     run()   })     return {     data,     run   } } ​ 复制代码

以上的写法是hook写法,里面使用到了 ref 、watch,很多小伙伴从Vue2过渡来Vue3的,对这块这样使用的接触的很少。使用高质量可靠的请求hook我相信后面会成为Vue3开发的一个趋势,下面我展示一下业务中的使用流程,展现它的魅力 😉

读取值:{{ data }} ​ import { ref } from 'vue' import { useRequest } from '..' //、、、、、业务代码 //、、、、、业务代码 const { data } = useRequest(() => getData(), { ready:true deps:[依赖其他响应式对象] }) 复制代码

比如这块业务代码,用户直接拿到处理好的请求的 data,它是一个响应式,所以业务层省去了一个声明响应式对象来保存数据的代码,ready 判断条件,业务层又被砍去一个条件判断函数,依赖刷新,砍去书写watch的代码,用户只需要关注配置即可,我们会发现它是通过 run方法调用触发请求的,那么,我们的防抖、节流函数只需要作用于 run 函数即可,所以这样的做法,是不是很简洁。

这一块的拓展性极强,你可以拓展 loading状态、params等出去。因为使用 async/await ,所以我们管理的请求API返回一个promise对象即可,意味着axios 和 request 这些都兼容,完全将请求这块的功能性的模块从业务层脱离,用户只需要关注配置和API接口!

const { data } = useRequest(() => getData(), { // 防抖 // 节流 // ready // 依赖刷新 // 格式化请求 ... }) 复制代码

几行配置下来,给人的感觉就清爽,而且维护起来那叫一个舒服。

🏃 Use 二次封装 axios 或者 其他请求工具 封装请求hook钩子 使用文件管理 API 接口,👆写的使用一个函数返回一个 promise 即可 业务层使用 hook 传配置即可 📌 额外tip

封装带有ts提示的axios axiosInstance 和大家常用的一样,AxiosRequestConfig 类型从 axios 导出。 注意: 因为这里没写拦截器,所以返回了一个多余的new Promise 让大家直观的看到,只需要接受返回的一个 Promise 对象即可,实际上不管是 axios 还是 request 本身返回的都是 Promsie 对象 的。

const request = ( url: string, options?: AxiosRequestConfig, ): Promise => { return new Promise((resolve, reject) => {   axiosInstance({     url,     ...options,   })     .then((res) => {       resolve(res?.data?.data);     })     .catch((err) => {       reject(err);     }); }); }; 复制代码

需要配合拦截器截取 res.data.data

const request = ( url: string, options?: AxiosRequestConfig, ): Promise => { return axiosInstance({url,...options}) }; 复制代码

请求函数示例 AnalysisReportType 为 数据返回预定的 data 类型,支持 ts

export async function getListReports( params?: {   reportGroup?: string | null;   sortCol?: 'visitUv' | 'uploadFileTime';   sortType?: string;   reportName?: string; }, ) { return request('/platform/report/listReports', {   params: { ...params, sortType: 2 }, }); } 复制代码

业务组件中

const { data } = useRequest(()=>getListReports(),{ ready:true, ...其他配置 }) 复制代码 👋 拿来吧你

由于vueuse没有这块的功能,我针对业务层写了一个 vue-hooks-plus库,完整的测试用例覆盖,高质量可靠,里面涵盖封装了一个 useRequest 钩子,自己公司已经用上,安全可靠,满足业务 99% 需求,并且支持按需引入,以下展示基本功能,更多详细见API文档 👇

const { loading: Ref, data?: Ref, error?: Ref, params: Ref, run: (...params: TParams) => void, runAsync: (...params: TParams) => Promise, refresh: () => void, refreshAsync: () => Promise, mutate: (data?: TData | ((oldData?: TData) => (TData | undefined))) => void, cancel: () => void, } = useRequest( service: (...args: TParams) => Promise, {   manual?: boolean,   defaultParams?: TParams,   formatResult?:(response:TData)=>any,   onBefore?: (params: TParams) => void,   onSuccess?: (data: TData, params: TParams) => void,   onError?: (e: Error, params: TParams) => void,   onFinally?: (params: TParams, data?: TData, e?: Error) => void, } ); 复制代码 ✒️ 划重点

作者整理出来一整套业务开发规范,快人一步的学会吧!

useRequest 保姆级业务开发教程

useRequest 国内文档地址

Github 地址

喜欢的小伙伴顺手点个 star 🌟 ,多多支持!

✨ 文档闪亮登场

iShot_2022-10-27_10.04.30.png

iShot_2022-10-27_10.03.35.png



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有